// 扩展vue原有的功能：全局组件，自定义指令，挂载原型方法，注意：没有全局过滤器。
// 这就是插件
// vue2.0插件写法要素：导出一个对象，有install函数，默认传入了Vue构造函数，Vue基础之上扩展
// vue3.0插件写法要素：导出一个对象，有install函数，默认传入了app应用实例，app基础之上扩展

// Vue2 全局注册组件
// Vue.component('组件名', 组件)

// Vue3 全局注册组件
// app.component('组件名', 组件)

// 骨架屏组件
// import XtxSkeleton from '@/components/library/xtx-skeleton'
// // 轮播图组件
// import XtxCarousel from '@/components/library/xtx-carousel'
// // 查看全部
// import XtxMore from '@/components/library/xtx-more'
// // 面包屑组件
// import XtxBread from '@/components/library/xtx-bread.vue'
// // 面包屑子组件
// import XtxBreadItem from '@/components/library/xtx-bread-item.vue'

import { useIntersectionObserver } from '@vueuse/core'
import defaultImg from '@/assets/images/200.png'

import Message from './Message'

/*
  组件库自动导入和注册
    - 使用 `require` 提供的函数 `context`  加载某一个目录下的所有 `.vue` 后缀的文件。
    - 然后 `context` 函数会返回一个导入函数 `importFn`
      - 它又一个属性 `keys() `  获取所有的文件路径
    - 通过文件路径数组，通过遍历数组，再使用 `importFn`  根据路径导入组件对象
    - 遍历的同时进行全局注册即可
*/

// require.context(目录路径, 是否加载子目录, 正则匹配文件后缀 )
// 注意：importFn 是一个函数，用于导入文件的
const importFn = require.context('./', false, /\.vue$/)
// console.dir(importFn)
// console.log(importFn)

export default {
  // 这种写法以后是提供给 app.use() 安装组件库用的
  install (app) {
    // 在app上进行扩展，app提供 component directive 函数
    // 如果要挂载原型 app.config.globalProperties 方式
    // app.component(XtxSkeleton.name, XtxSkeleton)
    // app.component(XtxCarousel.name, XtxCarousel)
    // app.component(XtxMore.name, XtxMore)
    // app.component(XtxBread.name, XtxBread)
    // app.component(XtxBreadItem.name, XtxBreadItem)

    // importFn.keys() 返回值是一个数组，存放文件名路径
    importFn.keys().forEach(item => {
      // 根据文件路径加载文件
      // 注意：这里需要 .default 才可以找到组件
      // console.log(item)
      // console.log(importFn(item))
      // 批量注册组件
      const component = importFn(item).default
      // console.log(component)
      // 全局自定义指定
      app.component(component.name, component)
    })

    defineDirective(app)

    // 想挂载全局的属性，选项式API可以通过 this.$message() 调用
    app.config.globalProperties.$message = Message
  }
}

const defineDirective = (app) => {
  app.directive('lazy', {
    mounted (el, { value }) {
      // stop 是一个函数，用于停止检测元素可见性
      const { stop } = useIntersectionObserver(
        el,
        // isIntersecting 布尔值，元素可见为 true，元素不可见为 false
        ([{ isIntersecting }], observerElement) => {
          // console.log('目标元素的可见性', isIntersecting)
          // 如果目标可见，发送请求
          el.style.backgroud = 'url(/img/load.88daf935.gif) no-repeat center / 50% 50%'
          if (isIntersecting) {
            // console.log('可以用lazy自定义指令替换src属性了')
            // 如果目标可见，替换图片地址，自动加载图片
            el.src = value
            // 如果图片地址是错误的，无法加载图片，显示占位图
            el.addEventListener('error', () => {
              el.src = defaultImg
            })
            // 主动停止检测元素可见性
            el.onload = () => {
              el.style.backgroud = ''
              stop()
            }
          }
        })
    }
  })
}
